module.exports.configGantt = function (missionList, totalWidth = 600, type = 'mission', mix=false) {
    let ganttList = [];
    let users = new Map();
    let start = new Date(missionList[0].start);
    let end = new Date(missionList[0].end);
    for (let item of missionList) {
        //step1 获取时间区间
        const tempStartDate = new Date(item.start);
        const tempEndDate = new Date(item.end);
        if (tempStartDate < start) {
            start = tempStartDate;
        }
        if (tempEndDate > end) {
            end = tempEndDate;
        }
        //step2 将任务按用户归属
        if (type === 'person') {
            let currentUser;
            if (users.has(item.userId)) {
                currentUser = users.get(item.userId);
            } else {
                currentUser = {
                    id: item.userId,
                    name: item.userName,
                    mission: []
                }
                users.set(item.userId, currentUser);
            }
            currentUser.mission.push(item);
        }
    }
    //将时间向前/后各扩展一天
    start = new Date((start.getTime()) - 1000 * 60 * 60 * 24 * 1);
    end = new Date((end.getTime()) + 1000 * 60 * 60 * 24 * 1);
    if (type === 'person') {
        users = [...users.values()];
    }
    const interval = totalWidth / ((end - start) / (1000 * 24 * 60 * 60));
    switch (type) {
        case 'mission':
            {
                ganttList = missionList.map(item => [item]);
                //向上填充
                if (mix !== false) {
                    for (let j = 1; j < ganttList.length; j++) {
                        //遍历下层元素列表
                        const ganttItemUp = ganttList[j];
                        if (ganttItemUp.length) {
                            for (let n = 0; n < ganttItemUp.length; n++) {
                                const itemJ = ganttItemUp[n];
                                const itemJStart = new Date(itemJ.start);
                                const itemJEnd = new Date(itemJ.end);
                                for (let i = 0; i < j; i++) {
                                    //遍历上层元素列表
                                    const gantItemDown = ganttList[i];
                                    if (gantItemDown.length) {
                                        for (let m = 0; m < gantItemDown.length; m++) {
                                            const itemI = gantItemDown[m];
                                            //如果下层起始时间小于上层开始时间
                                            if (itemJStart > new Date(itemI.end)) {
                                                if (m < gantItemDown.length - 1) {
                                                    //但上层元素后方还有其他元素
                                                    if (itemJEnd < new Date(gantItemDown[m + 1].start)) {
                                                        //偏偏下层元素终止时间小于上层元素后方元素的开始时间
                                                        //向上合并之
                                                        ganttList[i] = insetIntoArray(gantItemDown, itemJ, m);
                                                        ganttItemUp.splice(n, 1);
                                                        break;
                                                    }
                                                } else {
                                                    //并且上层元素后方不再有元素
                                                    gantItemDown.push(itemJ);
                                                    ganttItemUp.splice(n, 1);
                                                    break;
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                ganttList = ganttList.filter(item => {
                    if (!item.length) {
                        return false;
                    } else {
                        item.forEach(item => item = Object.assign(item, figureStyle(item, {
                            start,
                            interval
                        })))
                        return true;
                    }
                });
                break;
            }
        case 'person':
            {
                break;
            }
        case 'min':
            {
                break;
            }
        default:
    }
    return {
        ganttList,
        users,
        start,
        end,
        interval,
        totalWidth
    }
}

/**
 * 向数组中特定序号插入元素
 */
function insetIntoArray(array, item, index) {
    return [...array.splice(0, index), item, ...array]
}

/**
 * 计算甘特图样式
 */
function figureStyle(item, option) {
    const {
        start,
        interval
    } = {
        ...option
    }
    const startTime = ((new Date(item.start)) - (new Date(start))) / (1000 * 60 * 60 * 24);
    const duringTime = item.last;
    let percent = 0;
    switch (item.status) {
        case 'done':
            percent = 100;
            break;
        case 'doing':
            percent = (((new Date() - new Date(item.start)) / (1000 * 60 * 60 * 24)) / item.last * 100).toFixed(1);
            break;
    }

    return {
        left: startTime * interval,
        width: duringTime * interval,
        percent
    }
}